<?php
/**
 * SimplifyPHP Framework
 *
 * This file is part of SimplifyPHP Framework.
 *
 * SimplifyPHP Framework is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * SimplifyPHP Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Rodrigo Rutkoski Rodrigues, <rutkoski@gmail.com>
 * @copyright Copyright 2008 Rodrigo Rutkoski Rodrigues
 */

global $php_errno;

$php_errno = array(
  0 => 'E_NONE', 1 => 'E_ERROR', 2 => 'E_WARNING', 4 => 'E_PARSE', 8 => 'E_NOTICE', 16 => 'E_CORE_ERROR', 32 => 'E_CORE_WARNING', 64 => 'E_COMPILE_ERROR', 128 => 'E_COMPILE_WARNING', 
  256 => 'E_USER_ERROR', 512 => 'E_USER_WARNING', 1024 => 'E_USER_NOTICE', 2048 => 'E_STRICT', 4096 => 'E_RECOVERABLE_ERROR', 8192 => 'E_DEPRECATED', 16384 => 'E_USER_DEPRECATED', 
  30719 => 'E_ALL' 
);

foreach ($php_errno as $no => $err) {
  sy_define_once($err, $no);
}

function sy_exception_handler($e)
{
  if (SY_LOG_EXCEPTIONS) {
    sy_log('exception', array(
      $e->getMessage(), $e->getTraceAsString(), get_class($e) . ' in ' . $e->getFile() . ' on line ' . $e->getLine() . '' 
    ));
  }
  
  if (SY_DEBUG_LEVEL) {
    if (Simplify::getRequest() && Simplify::getRequest()->isAjax()) {
      $exc = array(
        
        'exception' => array(
          'class' => get_class($e), 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'file' => $e->getFile(), 'line' => $e->getLine() 
        ) 
      );
      
      ob_end_clean();
      
      header('Content-type: application/json; charset="utf-8"');
      
      echo json_encode($exc);
    }
    else {
      pre($e->getMessage());
      pre($e->getTraceAsString());
      pre(get_class($e) . ' - ' . $e->getFile() . ' - ' . $e->getLine());
    }
  }
}

function sy_log($file, $data, $lines = 300)
{
  static $logs;
  
  if (empty($logs))
    $logs = array();
  
  if (! Simplify::getConfig())
    return;
  
  $file = Simplify::getConfig()->get('app_dir') . '/logs/' . $file . '.log';
  
  $a = @file($file, FILE_IGNORE_NEW_LINES);
  if ($lines && count($a) > $lines) {
    $a = array_slice($a, count($a) - $lines);
  }
  
  if (! isset($logs[$file])) {
    $logs[$file] = true;
    $a[] = "-> started " . date('Y-m-d H:i:s');
  }
  
  $output = date('Y-m-d H:i:s') . ' -> ';
  
  if (! empty($data)) {
    if (is_string($data)) {
      $output .= trim($data);
    }
    elseif (is_a($data, 'IDictionary')) {
      $data = $data->getAll();
      array_walk_recursive($data, 'sy_array_map');
      $output .= var_export($data, true);
    }
    else {
      $output .= var_export($data, true);
    }
  }
  
  $a[] = $output;
  
  file_put_contents($file, implode("\n", $a));
}

function fatal_error_handler($buffer)
{
  global $php_errno;
  
  if ($error = error_get_last()) {
    switch ($error['type']) {
      case E_ERROR :
      case E_CORE_ERROR :
      case E_COMPILE_ERROR :
      case E_USER_ERROR :
        $ajax = Simplify::getRequest() && Simplify::getRequest()->isAjax();
        
        $err = sprintf('<b>%s</b>: %s in <b>%s</b> on line <b>%d</b>', $php_errno[$error['type']], $error['message'], $error['file'], $error['line']);
        
        if ($ajax) {
          header('Content-type: application/json; charset="utf-8"');
          $buffer = json_encode(array(
            'errors' => $err 
          ));
        }
        else {
          $buffer = $err;
        }
        
        if (SY_LOG_ERRORS) {
          sy_log('error', $err);
        }
        
        break;
    }
  }
  
  return $buffer;
}

function error_handler($errno, $errstr, $errfile, $errline)
{
  global $php_errno;
  
  $err = sprintf('<b>%s</b>: %s in <b>%s</b> on line <b>%d</b>', $php_errno[$errno], $errstr, $errfile, $errline);
  
  $catch = in_array($errno, array(
    E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR 
  ));
  
  if ($catch && SY_LOG_ERRORS) {
    sy_log('error', $err);
  }
  
  if ($catch) {
    if (Simplify::getRequest() && Simplify::getRequest()->isAjax()) {
      header('Content-type: application/json; charset="utf-8"');
      echo json_encode(array(
        'errors' => $err 
      ));
    }
    else {
      echo $err;
    }
    
    ob_flush();
    
    die();
  }
  elseif ($errno & error_reporting()) {
    echo '<br/>'.$err;
  }
  else {
    return false;
  }
}

sy_define_once('SY_DEBUG_LEVEL', 0);
sy_define_once('SY_LOG_EXCEPTIONS', true);
sy_define_once('SY_CATCH_ERRORS', true);
sy_define_once('SY_LOG_ERRORS', true);

set_exception_handler('sy_exception_handler');

switch (SY_DEBUG_LEVEL) {
  case 0 :
    error_reporting(E_NONE);
    ini_set('display_errors', 0);
    break;
  
  case 1 :
    error_reporting(E_ALL ^ (E_NOTICE | E_DEPRECATED));
    ini_set('display_errors', 1);
    break;
  
  case 2 :
    error_reporting(E_ALL ^ E_DEPRECATED);
    ini_set('display_errors', 1);
    break;
    
  default :
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
}

if (SY_CATCH_ERRORS) {
  ob_start("fatal_error_handler");
  set_error_handler("error_handler");
}

?>